home *** CD-ROM | disk | FTP | other *** search
/ Linux Cubed Series 8: LINUX Games / Linux Cubed Series 8 - LINUX Games.iso / games / muds / mordor_2.000 / mordor_2 / src / command4.c < prev    next >
C/C++ Source or Header  |  1995-06-28  |  22KB  |  878 lines

  1. /*
  2.  * COMMAND4.C:
  3.  *
  4.  *    Additional user routines
  5.  *
  6.  *    Copyright (C) 1991, 1992, 1993 Brett J. Vickers
  7.  *
  8.  */
  9.  
  10. #include "mstruct.h"
  11. #include "mextern.h"
  12. #include <sys/time.h>
  13. #include <string.h>
  14.  
  15. /**********************************************************************/
  16. /*                health                      */
  17. /**********************************************************************/
  18.  
  19. /* This function shows a player his current hit points, magic points,  */
  20. /* experience, gold and level.                           */
  21.  
  22. int health(ply_ptr, cmnd)
  23. creature    *ply_ptr;
  24. cmd        *cmnd;
  25. {
  26.     int    fd;
  27.  
  28.     fd = ply_ptr->fd;
  29.     
  30.     if(F_ISSET(ply_ptr, PBLIND)){
  31.         ANSI(fd, RED);
  32.         ANSI(fd, BOLD);
  33.         ANSI(fd, BLINK);
  34.         print(fd, "You're obviously blind!\n");
  35.         ANSI(fd, NORMAL);
  36.         ANSI(fd, WHITE);
  37.         return(0);
  38.     }
  39.         ANSI(fd, WHITE);
  40.     print(fd, "%s the %s (level %d)", ply_ptr->name, 
  41.         title_ply(ply_ptr), ply_ptr->level);
  42.     if(F_ISSET(ply_ptr, PHIDDN)) {
  43.         ANSI(fd, CYAN);
  44.         print(fd, " *Hidden* ");
  45.     }
  46.     if(F_ISSET(ply_ptr, PPOISN)) {
  47.         ANSI(fd, BLINK);
  48.         ANSI(fd, GREEN);
  49.         print(fd, " *Poisoned* ");
  50.         ANSI(fd, NORMAL);
  51.     }
  52.     if(F_ISSET(ply_ptr, PCHARM)) {
  53.         ANSI(fd, BOLD);
  54.         ANSI(fd, CYAN);
  55.         print(fd, " *Charmed* ");
  56.         ANSI(fd, NORMAL);
  57.     }
  58.     if(F_ISSET(ply_ptr, PSILNC)) {
  59.         ANSI(fd, BLINK);
  60.         ANSI(fd, MAGENTA);
  61.         print(fd, " *Mute* ");
  62.         ANSI(fd, NORMAL);
  63.     }
  64.     if(F_ISSET(ply_ptr, PDISEA)) {
  65.         ANSI(fd, BLINK);
  66.         ANSI(fd, RED);    
  67.         print(fd," *Diseased* ");
  68.         ANSI(fd, NORMAL);
  69.     }
  70.     ANSI(fd, GREEN);
  71.     print(fd, "\n %3d/%3d Hit Points    %3d/%3d Magic Points",
  72.         ply_ptr->hpcur, ply_ptr->hpmax, ply_ptr->mpcur, ply_ptr->mpmax);
  73.     ANSI(fd, RED);
  74.     print(fd, "    AC: %d\n", ply_ptr->armor/10);
  75.     ANSI(fd, YELLOW);
  76.     print(fd, " %7ld Experience    %7ld Gold Pieces\n",
  77.         ply_ptr->experience, ply_ptr->gold);
  78.     ANSI(fd, NORMAL);
  79.     ANSI(fd, WHITE);
  80.     return(0);
  81. }
  82.  
  83. /**********************************************************************/
  84. /*                help                      */
  85. /**********************************************************************/
  86.  
  87. /* This function allows a player to get help in general, or help for a */
  88. /* specific command.  If help is typed by itself, a list of commands   */
  89. /* is produced.  Otherwise, help is supplied for the command specified */
  90.  
  91. int help(ply_ptr, cmnd)
  92. creature    *ply_ptr;
  93. cmd        *cmnd;
  94. {
  95.     char     file[80];
  96.     int    fd, c=0, match=0, num=0;
  97.     
  98.     fd = ply_ptr->fd;
  99.     strcpy(file, DOCPATH);
  100.  
  101.     if(cmnd->num < 2) {
  102.         strcat(file, "/helpfile");
  103.         view_file(fd, 1, file);
  104.         return(DOPROMPT);
  105.     }
  106.     if(!strcmp(cmnd->str[1], "spells")) {
  107.         strcat(file, "/spellfile");
  108.         view_file(fd, 1, file);
  109.         return(DOPROMPT);
  110.     }
  111.  
  112.     if(!strcmp(cmnd->str[1], "policy")) {
  113.         strcat(file, "/policy");
  114.         view_file(fd, 1, file);
  115.         return(DOPROMPT);
  116.     }
  117.  
  118.     do {
  119.         if(!strcmp(cmnd->str[1], cmdlist[c].cmdstr)) {
  120.             match = 1;
  121.             num = c;
  122.             break;
  123.         }
  124.         else if(!strncmp(cmnd->str[1], cmdlist[c].cmdstr, 
  125.             strlen(cmnd->str[1]))) {
  126.             match++;
  127.             num = c;
  128.         }
  129.         c++;
  130.     } while(cmdlist[c].cmdno);
  131.  
  132.     if(match == 1) {
  133.         sprintf(file, "%s/help.%d", DOCPATH, cmdlist[num].cmdno);
  134.         view_file(fd, 1, file);
  135.         return(DOPROMPT);
  136.     }
  137.     else if(match > 1) {
  138.         print(fd, "Command is not unique.\n");
  139.         return(0);
  140.     }
  141.  
  142.     c = num = 0;
  143.     do {
  144.         if(!strcmp(cmnd->str[1], spllist[c].splstr)) {
  145.             match = 1;
  146.             num = c;
  147.             break;
  148.         }
  149.         else if(!strncmp(cmnd->str[1], spllist[c].splstr, 
  150.             strlen(cmnd->str[1]))) {
  151.             match++;
  152.             num = c;
  153.         }
  154.         c++;
  155.     } while(spllist[c].splno != -1);
  156.  
  157.     if(match == 0) {
  158.         print(fd, "That command does not exist.\n");
  159.         return(0);
  160.     }
  161.     else if(match > 1) {
  162.         print(fd, "Spell name not unique.\n");
  163.         return(0);
  164.     }
  165.  
  166.     sprintf(file, "%s/spell.%d", DOCPATH, spllist[num].splno);
  167.     view_file(fd, 1, file);
  168.     return(DOPROMPT);
  169. }
  170.  
  171. /**********************************************************************/
  172. /*                welcome                      */
  173. /**********************************************************************/
  174.  
  175. /* Outputs welcome file to user, giving him/her info on how to play   */
  176. /* the game                                   */
  177.  
  178. int welcome(ply_ptr, cmnd)
  179. creature    *ply_ptr;
  180. cmd        *cmnd;
  181. {
  182.     char    file[80];
  183.     int    fd;
  184.  
  185.     fd = ply_ptr->fd;
  186.  
  187.     sprintf(file, "%s/welcome", DOCPATH);
  188.  
  189.     view_file(fd, 1, file);
  190.     return(DOPROMPT);
  191. }
  192.  
  193. /**********************************************************************/
  194. /*                info                      */
  195. /**********************************************************************/
  196.  
  197. /* This function displays a player's entire list of information, including */
  198. /* player stats, proficiencies, level and class.               */
  199.  
  200. int info(ply_ptr, cmnd)
  201. creature    *ply_ptr;
  202. cmd        *cmnd;
  203. {
  204.     char    alstr[8];
  205.     int     fd, cnt;
  206.     long    expneeded, lv;
  207.  
  208.     fd = ply_ptr->fd;
  209.  
  210.     update_ply(ply_ptr);
  211.  
  212.     if(ply_ptr->level < MAXALVL)
  213.         expneeded = needed_exp[ply_ptr->level -1];
  214.     else
  215.             expneeded = (long)((needed_exp[MAXALVL-1]*ply_ptr->level));   
  216.  
  217.     if(ply_ptr->alignment < -100)
  218.         strcpy(alstr, "Evil");
  219.     else if(ply_ptr->alignment < 101)
  220.         strcpy(alstr, "Neutral");
  221.     else
  222.         strcpy(alstr, "Good");
  223.  
  224.     for(lv=0,cnt=0; lv<MAXWEAR; lv++)
  225.         if(ply_ptr->ready[lv]) cnt++;
  226.     cnt += count_inv(ply_ptr, 0);
  227.  
  228.     print(fd, "\n%s the %s:\n\n", ply_ptr->name, title_ply(ply_ptr));
  229.  
  230.     print(fd, "Level: %-20d       Race: %s\n",
  231.         ply_ptr->level, race_str[ply_ptr->race]);
  232.     print(fd, "Class: %-20s  Alignment: %s %s\n",
  233.         class_str[ply_ptr->class],
  234.         F_ISSET(ply_ptr, PCHAOS) ? "Chaotic":"Lawful", alstr);
  235.  
  236. #define INTERVAL ply_ptr->lasttime[LT_HOURS].interval
  237.     print(fd, "Time played: ");
  238.     if(INTERVAL > 86400L)
  239.         print(fd, "%d day%s, ", INTERVAL/86400L,
  240.         INTERVAL/86400L == 1 ? "":"s");
  241.     if(INTERVAL > 3600L)
  242.         print(fd, "%d hour%s, ", (INTERVAL % 86400L)/3600L,
  243.         (INTERVAL % 86400L)/3600L == 1 ? "":"s");
  244.     print(fd, "%d minute%s\n\n", (INTERVAL % 3600L)/60L,
  245.         (INTERVAL %3600L)/60L == 1 ? "":"s");
  246.  
  247.     print(fd, "Str: %-2d     Dex: %-2d     Con: %-2d\n",
  248.           ply_ptr->strength, ply_ptr->dexterity, ply_ptr->constitution);
  249.     print(fd, "Int: %-2d     Pty: %-2d\n\n",
  250.           ply_ptr->intelligence, ply_ptr->piety);
  251.     print(fd,
  252.      "  Hit Points: %-4d/%-4d         Experience: %lu (%lu more needed)\n", 
  253.      ply_ptr->hpcur, ply_ptr->hpmax, ply_ptr->experience, 
  254.      MAX(0, expneeded-ply_ptr->experience));
  255.     print(fd, "Magic Points: %-4d/%-4d               Gold: %-7lu\n",
  256.           ply_ptr->mpcur, ply_ptr->mpmax, ply_ptr->gold);
  257.     print(fd, " Armor Class: %-4d        Inventory Weight: %d lbs (%d items).\n\n", 
  258.           ply_ptr->armor/10, weight_ply(ply_ptr), cnt);
  259.  
  260.     print(fd, "Proficiencies:\n");
  261.     print(fd, "Sharp: %2d%%    Thrust: %2d%%   Blunt: %2d%%\n",
  262.           profic(ply_ptr, SHARP), profic(ply_ptr, THRUST),
  263.           profic(ply_ptr, BLUNT));
  264.     print(fd, " Pole: %2d%%   Missile: %2d%%\n\n",
  265.           profic(ply_ptr, POLE), profic(ply_ptr, MISSILE));
  266.  
  267.     print(fd, "Magical Realms:\n");
  268.     print(fd,
  269.       "Earth: %2d%%      Wind: %2d%%    Fire: %2d%%   Water: %2d%%\n\n",
  270.         mprofic(ply_ptr, EARTH), mprofic(ply_ptr, WIND),
  271.         mprofic(ply_ptr, FIRE), mprofic(ply_ptr, WATER));
  272.  
  273.     F_SET(ply_ptr, PREADI);
  274.     print(fd, "[Hit Return, Q to Quit]: ");
  275.     output_buf();
  276.     Ply[fd].io->intrpt &= ~1;
  277.     Ply[fd].io->fn = info_2;
  278.     Ply[fd].io->fnparam = 1;
  279.     return(DOPROMPT);
  280. }
  281.  
  282. /************************************************************************/
  283. /*                info_2                    */
  284. /************************************************************************/
  285.  
  286. /* This function is the second half of info which outputs spells    */
  287.  
  288. void info_2(fd, param, instr)
  289. int     fd, param;
  290. char     *instr;
  291. {
  292.     char        str[2048];
  293.     char        spl[128][20];
  294.     int        i, j;
  295.     creature    *ply_ptr;
  296.  
  297.     ply_ptr = Ply[fd].ply;
  298.  
  299.     if(instr[0]) {
  300.         print(fd, "Aborted.\n");
  301.         F_CLR(ply_ptr, PREADI);
  302.         RETURN(fd, command, 1);
  303.     }
  304.  
  305.     strcpy(str, "\nSpells known: ");
  306.     for(i=0,j=0; i<128; i++)
  307.         if(S_ISSET(ply_ptr, i))
  308.             strcpy(spl[j++], spllist[i].splstr);
  309.  
  310.     if(!j)
  311.         strcat(str, "None.");
  312.     else {
  313.         qsort((void *)spl, j, 20, strcmp);
  314.         for(i=0; i<j; i++) {
  315.             strcat(str, spl[i]);
  316.             strcat(str, ", ");
  317.         }
  318.         str[strlen(str)-2] = '.';
  319.         str[strlen(str)-1] = 0;
  320.     }
  321.     print(fd, "%s\n", str);
  322.  
  323.     strcpy(str, "Spells under: ");
  324.     if(F_ISSET(ply_ptr, PBLESS)) strcat(str, "bless, ");
  325.     if(F_ISSET(ply_ptr, PLIGHT)) strcat(str, "light, ");
  326.     if(F_ISSET(ply_ptr, PPROTE)) strcat(str, "protection, ");
  327.     if(F_ISSET(ply_ptr, PINVIS)) strcat(str, "invisibility, ");
  328.     if(F_ISSET(ply_ptr, PDINVI)) strcat(str, "detect-invisible, ");
  329.     if(F_ISSET(ply_ptr, PDMAGI)) strcat(str, "detect-magic, ");
  330.     if(F_ISSET(ply_ptr, PLEVIT)) strcat(str, "levitation, ");
  331.     if(F_ISSET(ply_ptr, PRFIRE)) strcat(str, "resist-fire, ");
  332.     if(F_ISSET(ply_ptr, PFLYSP)) strcat(str, "fly, ");
  333.     if(F_ISSET(ply_ptr, PRMAGI)) strcat(str, "resist-magic, ");
  334.     if(F_ISSET(ply_ptr, PKNOWA)) strcat(str, "know-aura, ");
  335.     if(F_ISSET(ply_ptr, PRCOLD)) strcat(str, "resist-cold, ");
  336.     if(F_ISSET(ply_ptr, PBRWAT)) strcat(str, "breathe-water, ");
  337.     if(F_ISSET(ply_ptr, PSSHLD)) strcat(str, "earth-shield, ");
  338.     if(strlen(str) == 14)
  339.         strcat(str, "None.");
  340.     else {
  341.         str[strlen(str)-2] = '.';
  342.         str[strlen(str)-1] = 0;
  343.     }
  344.     print(fd, "%s\n\n", str);
  345.  
  346.     F_CLR(Ply[fd].ply, PREADI);
  347.     RETURN(fd, command, 1);
  348. }
  349.  
  350. /**********************************************************************/
  351. /*                send                      */
  352. /**********************************************************************/
  353.  
  354. /* This function allows a player to send a message to another player.  If */
  355. /* the other player is logged in, the message is sent successfully.       */
  356.  
  357. int send(ply_ptr, cmnd)
  358. creature    *ply_ptr;
  359. cmd        *cmnd;
  360. {
  361.     creature    *crt_ptr = 0;
  362.     etag        *ign;
  363.     int        spaces=0, i, fd;
  364.     int         len;
  365.  
  366.     fd = ply_ptr->fd;
  367.  
  368.     if(cmnd->num < 2) {
  369.         print(fd, "Send to whom?\n");
  370.         return 0;
  371.     }
  372.  
  373.     cmnd->str[1][0] = up(cmnd->str[1][0]);
  374.     for(i=0; i<Tablesize; i++) {
  375.         if(!Ply[i].ply) continue;
  376.         if(Ply[i].ply->fd == -1) continue;
  377.         if(F_ISSET(Ply[i].ply, PDMINV) && ply_ptr->class < CARETAKER) 
  378.             continue;
  379.         if(!strncmp(Ply[i].ply->name, cmnd->str[1], 
  380.            strlen(cmnd->str[1])))
  381.             crt_ptr = Ply[i].ply;
  382.         if(!strcmp(Ply[i].ply->name, cmnd->str[1]))
  383.             break;
  384.     }
  385.     if(!crt_ptr) {
  386.         print(fd, "Send to whom?\n");
  387.         return(0);
  388.     }
  389.     if(ply_ptr->class < CARETAKER && (F_ISSET(crt_ptr, PINVIS) && !F_ISSET(ply_ptr, PDINVI))) {
  390.         print(fd, "Send to whom?\n");
  391.         return(0);
  392.     }
  393.      if(F_ISSET(crt_ptr, PIGNOR) && (ply_ptr->class < CARETAKER)) {
  394.         print(fd, "%s is ignoring everyone.\n", crt_ptr->name);
  395.         return(0);
  396.     }
  397.  
  398.     ign = Ply[crt_ptr->fd].extr->first_ignore;
  399.     while(ign) {
  400.         if(!strcmp(ign->enemy, ply_ptr->name)) {
  401.             print(fd, "%s is ignoring you.\n", crt_ptr->name);
  402.             return(0);
  403.         }
  404.         ign = ign->next_tag;
  405.     }
  406.     
  407.     len = strlen(cmnd->fullstr);
  408.     for(i=0; i< len && i<256; i++) {
  409.         if(cmnd->fullstr[i] == ' ' && cmnd->fullstr[i+1] != ' ')
  410.             spaces++;
  411.         if(spaces==2) break;
  412.     }
  413.     cmnd->fullstr[255] = 0;
  414.  
  415.     if(spaces < 2 || strlen(&cmnd->fullstr[i+1]) < 1) {
  416.         print(fd, "Send what?\n");
  417.         return(0);
  418.     }
  419.     if(F_ISSET(ply_ptr, PSILNC)) {
  420.         print(fd, "You can't speak.\n");
  421.         return(0);
  422.     }
  423.     if(F_ISSET(ply_ptr, PLECHO)){
  424.                 ANSI(fd, CYAN);
  425.                 print(fd, "You sent: \"%s\" to %M.\n", &cmnd->fullstr[i+1], crt_ptr);
  426.                 ANSI(fd, NORMAL)
  427.         }
  428.         else
  429.         print(fd, "Message sent to %s.\n", crt_ptr->name);
  430.     
  431.     print(crt_ptr->fd, "### %M just flashed, \"%s\".\n", ply_ptr,
  432.           &cmnd->fullstr[i+1]);
  433.  
  434.     if(ply_ptr->class > CARETAKER || crt_ptr->class > CARETAKER)
  435.         return(0);
  436.  
  437.     broadcast_eaves("--- %s sent to %s, \"%s\".", ply_ptr->name,
  438.              crt_ptr->name, &cmnd->fullstr[i+1]);
  439.  
  440.     return(0);
  441.  
  442. }
  443.  
  444. /**********************************************************************/
  445. /*                broadsend                  */
  446. /**********************************************************************/
  447.  
  448. /* This function is used by players to broadcast a message to every   */
  449. /* player in the game.  Broadcasts by players are of course limited,  */
  450. /* so the number used that day is checked before the broadcast is     */
  451. /* allowed.                                  */
  452.  
  453. int broadsend(ply_ptr, cmnd)
  454. creature    *ply_ptr;
  455. cmd        *cmnd;
  456. {
  457.     int    i, found=0, fd;
  458.     int     len;
  459.  
  460.     fd = ply_ptr->fd;
  461.     len = strlen(cmnd->fullstr);
  462.     for(i=0; i<len && i < 256; i++) {
  463.         if(cmnd->fullstr[i] == ' ' && cmnd->fullstr[i+1] != ' ')
  464.             found++;
  465.         if(found==1) break;
  466.     }
  467.     cmnd->fullstr[255] = 0;
  468.  
  469.     if(found < 1 || strlen(&cmnd->fullstr[i+1]) < 1) {
  470.         print(fd, "Send what?\n");
  471.         return(0);
  472.     }
  473.  
  474.     if(!dec_daily(&ply_ptr->daily[DL_BROAD])) {
  475.         print(fd,"You've used up all your broadcasts today.\n");
  476.         return(0);
  477.     }
  478.     if(F_ISSET(ply_ptr, PSILNC)) {
  479.         print(fd, "Your voice is too weak to do that.\n");
  480.         return(0);
  481.     }
  482.     print(fd, "Message broadcast.\n");
  483.     broadcast("### %M broadcasted, \"%s\".", ply_ptr, &cmnd->fullstr[i+1]);
  484.  
  485.     return(0);
  486.  
  487. }
  488.  
  489. /**********************************************************************/
  490. /*                follow                      */
  491. /**********************************************************************/
  492.  
  493. /* This command allows a player (or a monster) to follow another player. */
  494. /* Follow loops are not allowed; i.e. you cannot follow someone who is   */
  495. /* following you.  Also, you cannot follow yourself.             */
  496.  
  497. int follow(ply_ptr, cmnd)
  498. creature    *ply_ptr;
  499. cmd        *cmnd;
  500. {
  501.     creature    *old_ptr, *new_ptr;
  502.     room        *rom_ptr;
  503.     ctag        *cp, *pp, *prev;
  504.     int        fd;
  505.  
  506.     fd = ply_ptr->fd;
  507.     rom_ptr = ply_ptr->parent_rom;
  508.  
  509.     if(cmnd->num < 2) {
  510.         print(fd, "Follow who?\n");
  511.         return(0);
  512.     }
  513.  
  514.     F_CLR(ply_ptr, PHIDDN);
  515.     lowercize(cmnd->str[1], 1);
  516.     new_ptr = find_crt(ply_ptr, rom_ptr->first_ply,
  517.                cmnd->str[1], cmnd->val[1]);
  518.  
  519.     if(!new_ptr) {
  520.         print(fd, "No one here by that name.\n");
  521.         return(0);
  522.     }
  523.  
  524.     if(new_ptr == ply_ptr && !ply_ptr->following) {
  525.         print(fd, "You can't follow yourself.\n");
  526.         return(0);
  527.     }
  528.  
  529.     if(new_ptr->following == ply_ptr) {
  530.         print(fd, "You can't.  %s's following you.\n",
  531.               F_ISSET(new_ptr, PMALES) ? "He":"She");
  532.         return(0);
  533.     }
  534.  
  535.     if(ply_ptr->following) {
  536.         old_ptr = ply_ptr->following;
  537.         cp = old_ptr->first_fol;
  538.         if(cp->crt == ply_ptr) {
  539.             old_ptr->first_fol = cp->next_tag;
  540.             free(cp);
  541.         }
  542.         else while(cp) {
  543.             if(cp->crt == ply_ptr) {
  544.                 prev->next_tag = cp->next_tag;
  545.                 free(cp);
  546.                 break;
  547.             }
  548.             prev = cp;
  549.             cp = cp->next_tag;
  550.         }
  551.         ply_ptr->following = 0;
  552.         print(fd, "You stop following %s.\n", old_ptr->name);
  553.         if(!F_ISSET(ply_ptr, PDMINV))
  554.             print(old_ptr->fd, "%M stops following you.\n", 
  555.                   ply_ptr);
  556.     }
  557.  
  558.     if(ply_ptr == new_ptr)
  559.         return(0);
  560.  
  561.     ply_ptr->following = new_ptr;
  562.  
  563.     pp = (ctag *)malloc(sizeof(ctag));
  564.     if(!pp)
  565.         merror("follow", FATAL);
  566.     pp->crt = ply_ptr;
  567.     pp->next_tag = 0;
  568.  
  569.     if(!new_ptr->first_fol)
  570.         new_ptr->first_fol = pp;
  571.     else {
  572.         pp->next_tag = new_ptr->first_fol;
  573.         new_ptr->first_fol = pp;
  574.     }
  575.  
  576.     print(fd, "You start following %s.\n", new_ptr->name);
  577.     if(!F_ISSET(ply_ptr, PDMINV)) {
  578.         print(new_ptr->fd, "%M starts following you.\n", ply_ptr);
  579.         broadcast_rom2(fd, new_ptr->fd, ply_ptr->rom_num,
  580.                   "%M follows %m.", ply_ptr, new_ptr);
  581.     }
  582.  
  583.     return(0);
  584.  
  585. }
  586.  
  587. /**********************************************************************/
  588. /*                lose                      */
  589. /**********************************************************************/
  590.  
  591. /* This function allows a player to lose another player who might be  */
  592. /* following him.  When successful, that player will no longer be     */
  593. /* following.                                  */
  594.  
  595. int lose(ply_ptr, cmnd)
  596. creature    *ply_ptr;
  597. cmd        *cmnd;
  598. {
  599.     creature    *crt_ptr;
  600.     ctag        *cp, *prev;
  601.     int        fd;
  602.  
  603.     fd = ply_ptr->fd;
  604.  
  605. if(cmnd->num == 1) {
  606.  
  607.                 if (ply_ptr->following == 0){
  608.                         print(fd, "You're not following anyone.\n");
  609.                         return(0);
  610.  
  611.                 }
  612.       crt_ptr = ply_ptr->following;
  613.         cp = crt_ptr->first_fol;
  614.         if(cp->crt == ply_ptr) {
  615.                 crt_ptr->first_fol = cp->next_tag;
  616.                 free(cp);
  617.         }
  618.         else while(cp) {
  619.                 if(cp->crt == ply_ptr) {
  620.                         prev->next_tag = cp->next_tag;
  621.                         free(cp);
  622.                         break;
  623.                 }
  624.                 prev = cp;
  625.                 cp = cp->next_tag;
  626.         }
  627.         ply_ptr->following = 0; 
  628.                 print(fd,"You stop following %m\n",crt_ptr);
  629.                 if (!F_ISSET(ply_ptr,PDMINV))
  630.                         print(crt_ptr->fd,"%M stops following you\n",ply_ptr);
  631.                 return(0);
  632.         }                   
  633.  
  634.     F_CLR(ply_ptr, PHIDDN);
  635.  
  636.     lowercize(cmnd->str[1], 1);
  637.     crt_ptr = find_crt(ply_ptr, ply_ptr->first_fol,
  638.                cmnd->str[1], cmnd->val[1]);
  639.  
  640.     if(!crt_ptr) {
  641.         print(fd, "That person is not following you.\n");
  642.         return(0);
  643.     }
  644.  
  645.     if(crt_ptr->following != ply_ptr) {
  646.         print(fd, "That person is not following you.\n");
  647.         return(0);
  648.     }
  649.  
  650.     cp = ply_ptr->first_fol;
  651.     if(cp->crt == crt_ptr) {
  652.         ply_ptr->first_fol = cp->next_tag;
  653.         free(cp);
  654.     }
  655.     else while(cp) {
  656.         if(cp->crt == crt_ptr) {
  657.             prev->next_tag = cp->next_tag;
  658.             free(cp);
  659.             break;
  660.         }
  661.         prev = cp;
  662.         cp = cp->next_tag;
  663.     }
  664.     crt_ptr->following = 0;
  665.  
  666.     print(fd, "You lose %s.\n", F_ISSET(crt_ptr, PMALES) ? "him":"her");
  667.     if(!F_ISSET(ply_ptr, PDMINV)) {
  668.         print(crt_ptr->fd, "%M loses you.\n", ply_ptr);
  669.         broadcast_rom2(fd, crt_ptr->fd, "%M loses %m.", 
  670.                    ply_ptr, crt_ptr);
  671.     }
  672.  
  673.     return(0);
  674.  
  675. }
  676.  
  677. /**********************************************************************/
  678. /*                group                      */
  679. /**********************************************************************/
  680.  
  681. /* This function allows you to see who is in a group or party of people */
  682. /* who are following you.                        */
  683.  
  684. int group(ply_ptr, cmnd)
  685. creature    *ply_ptr;
  686. cmd        *cmnd;
  687. {
  688.     ctag    *cp;
  689.     char    str[2048];
  690.     int    fd, found = 0;
  691.  
  692.     fd = ply_ptr->fd;
  693.  
  694.     cp = ply_ptr->first_fol;
  695.     if(!cp) {
  696.         print(fd, "No one is following you.\n");
  697.         return(0);
  698.     }
  699.  
  700.     strcpy(str, "People in your group: ");
  701.     while(cp) {
  702.         if(!F_ISSET(cp->crt, PDMINV)) {
  703.             strcat(str, crt_str(cp->crt, 0, 0));
  704.             strcat(str, ", ");
  705.             found = 1;
  706.         }
  707.         cp = cp->next_tag;
  708.     }
  709.  
  710.     if(!found) {
  711.         print(fd, "No one is following you.\n");
  712.         return(0);
  713.     }
  714.  
  715.     str[strlen(str)-2] = 0;
  716.     print(fd, "%s.\n", str);
  717.  
  718.     return(0);
  719.  
  720. }
  721.  
  722. /**********************************************************************/
  723. /*                track                      */
  724. /**********************************************************************/
  725.  
  726. /* This function is the routine that allows rangers to search for tracks */
  727. /* in a room.  If the ranger is successful, he will be told what dir-    */
  728. /* ection the last person who was in the room left.             */
  729.  
  730. int track(ply_ptr, cmnd)
  731. creature    *ply_ptr;
  732. cmd        *cmnd;
  733. {
  734.     long    i, t;
  735.     int    fd, chance;
  736.  
  737.     fd = ply_ptr->fd;
  738.  
  739.     if(ply_ptr->class != RANGER && ply_ptr->class < CARETAKER) {
  740.         print(fd, "Only rangers can track.\n");
  741.         return(0);
  742.     }
  743.  
  744.     F_CLR(ply_ptr, PHIDDN);
  745.  
  746.     t = time(0);
  747.     i = LT(ply_ptr, LT_TRACK);
  748.  
  749.     if(t < i) {
  750.         please_wait(fd, i-t);
  751.         return(0);
  752.     }
  753.  
  754.     ply_ptr->lasttime[LT_TRACK].ltime = t;
  755.     ply_ptr->lasttime[LT_TRACK].interval = 5 - bonus[ply_ptr->dexterity];
  756.     
  757.     if(F_ISSET(ply_ptr, PBLIND)) {
  758.         print(fd, "You're blind...how can you see tracks?\n");
  759.         return(0);
  760.     }
  761.     chance = 25 + (bonus[ply_ptr->dexterity] + ply_ptr->level)*5;
  762.  
  763.     if(mrand(1,100) > chance) {
  764.         print(fd, "You fail to find any tracks.\n");
  765.         return(0);
  766.     }
  767.  
  768.     if(!ply_ptr->parent_rom->track[0]) {
  769.         print(fd, "There are no tracks in this room.\n");
  770.         return(0);
  771.     }
  772.  
  773.     print(fd, "You find tracks leading to the %s.\n",
  774.           ply_ptr->parent_rom->track);
  775.     broadcast_rom(fd, ply_ptr->rom_num, "%M finds tracks.", ply_ptr);
  776.  
  777.     return(0);
  778.  
  779. }
  780.  
  781. /**********************************************************************/
  782. /*                peek                      */
  783. /**********************************************************************/
  784.  
  785. /* This function allows a thief or assassin to peek at the inventory of */
  786. /* another player.  If successful, they will be able to see it and      */
  787. /* another roll is made to see if they get caught.            */
  788.  
  789. int peek(ply_ptr, cmnd)
  790. creature    *ply_ptr;
  791. cmd        *cmnd;
  792. {
  793.     creature    *crt_ptr;
  794.     room        *rom_ptr;
  795.     char        str[2048];
  796.     long        i, t;
  797.     int        fd, n, chance;
  798.  
  799.     fd = ply_ptr->fd;
  800.     rom_ptr = ply_ptr->parent_rom;
  801.     str[0] = 0;
  802.  
  803.     if(cmnd->num < 2) {
  804.         print(fd, "Peek at who?\n");
  805.         return(0);
  806.     }
  807.  
  808.     if(ply_ptr->class != THIEF && ply_ptr->class < CARETAKER) {
  809.         print(fd, "Only thieves can peek.\n");
  810.         return(0);
  811.     }
  812.     
  813.     if(F_ISSET(ply_ptr, PBLIND)){
  814.         ANSI(fd, RED);
  815.         print(fd, "You can't do that...You're blind!\n");
  816.         ANSI(fd, WHITE);
  817.         return(0);
  818.     }
  819.  
  820.     crt_ptr = find_crt(ply_ptr, rom_ptr->first_mon,
  821.                cmnd->str[1], cmnd->val[1]);
  822.  
  823.     if(!crt_ptr) {
  824.         lowercize(cmnd->str[1], 1);
  825.         crt_ptr = find_crt(ply_ptr, rom_ptr->first_ply,
  826.                    cmnd->str[1], cmnd->val[1]);
  827.  
  828.         if(!crt_ptr) {
  829.             print(fd, "That person is not here.\n");
  830.             return(0);
  831.         }
  832.     }
  833.  
  834.     i = LT(ply_ptr, LT_PEEKS);
  835.     t = time(0);
  836.  
  837.     if(i > t) {
  838.         please_wait(fd, i-t);
  839.         return(0);
  840.     }
  841.  
  842.     ply_ptr->lasttime[LT_PEEKS].ltime = t;
  843.     ply_ptr->lasttime[LT_PEEKS].interval = 5;
  844.  
  845.     if((F_ISSET(crt_ptr, MUNSTL) || F_ISSET(crt_ptr, MTRADE) || F_ISSET(crt_ptr, MPURIT)) && ply_ptr->class < DM) {        
  846.         print(fd, "You shouldn't do that, someone will think you are a thief.\n");  
  847.         return(0);            
  848.     } 
  849.         
  850.     chance = (25 + ply_ptr->level*10)-(crt_ptr->level*5);
  851.     if (chance<0) chance=0;
  852.     if (ply_ptr->class >= CARETAKER) chance=100;
  853.     if(mrand(1,100) > chance) {
  854.         print(fd, "You failed.\n");
  855.         return(0);
  856.     }
  857.  
  858.     chance = MIN(90, 15 + ply_ptr->level*5);
  859.  
  860.     if(mrand(1,100) > chance && ply_ptr->class < CARETAKER) {
  861.         print(crt_ptr->fd, "%s peeked at your inventory.\n", ply_ptr);
  862.         broadcast_rom2(fd, crt_ptr->fd, ply_ptr->rom_num, 
  863.                    "%M peeked at %m's inventory.", 
  864.                    ply_ptr, crt_ptr);
  865.     }
  866.  
  867.     sprintf(str, "%s is carrying: ", F_ISSET(crt_ptr, PMALES) ? "He":"She");
  868.     n = strlen(str);
  869.     if(list_obj(&str[n], ply_ptr, crt_ptr->first_obj) > 0)
  870.         print(fd, "%s\n", str);
  871.     else
  872.         print(fd, "%s isn't holding anything.\n",
  873.               F_ISSET(crt_ptr, PMALES) ? "He":"She");
  874.  
  875.     return(0);
  876.  
  877. }
  878.